package com.fashion.server.common.log;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 请求输入输出文件日志
 * @author WangXin
 *
 */
public class Log4jPrintAspect{

	private static final Logger logger = Logger.getLogger(Log4jPrintAspect.class);

	public Object doAroundHander(ProceedingJoinPoint joinPoint)
			throws Throwable {
		
		beforeHander();
		
		Date beforDate = new Date();
		long befor = beforDate.getTime();
		
		Object result = joinPoint.proceed();
		
		afterHander(befor, result);
		return result;
	}

	private void afterHander(long befor, Object result) {
		try {
			Date endDate = new Date();
			long end = endDate.getTime();
			String costStr = (end - befor)+"";
			Double cost = Double.valueOf(costStr)/1000;
			MDC.put("cost", cost);
			 //请求开始日志
			String infoStrEnd;
			infoStrEnd = "[response:"+result.toString()+"]";
			infoStrEnd = Log4jPrintAspect.subStr(infoStrEnd);
			logger.info(infoStrEnd);
			//清除mdc信息
			removeMDC();
		} catch (Exception e) {
			logger.error(e);
		}
	}

	private void beforeHander() {
		try {
			HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes()).getRequest();

			/**
			 * 获取线程id
			 */
			Long tId = Thread.currentThread().getId();

			/**
			 * 获取请求ip地址
			 */
			String ipAddress = getIpAddress(request);

			/**
			 * 获取url
			 */
			StringBuffer url = request.getRequestURL();

			//請求參數
			String requestParams = JSON.toJSONString(request.getParameterMap());

			String g_logid = request.getHeader("G_LOGID");
            String g_reqid = request.getHeader("G_REQID");

			/**
			 * RequestId
			 */
			String requestId = getRequestId();
			
			String referer = request.getHeader("Referer");
			if (referer == null) {
				referer = "";
			}
			/**
			 * 存储到MDC  里
			 */
			MDC.put("ipAddress", ipAddress);
			MDC.put("url", url);
			MDC.put("params", requestParams);
			MDC.put("tId", tId);
			MDC.put("reqId", requestId);
			MDC.put("refer", referer);
			MDC.put("errno", "");
			MDC.put("cost", "");
            MDC.put("g_logid",g_logid==null?"":g_logid);
            MDC.put("g_reqid",g_reqid==null?"":g_reqid);
			//请求开始日志
			String infoStr;
			infoStr = "[request:"+url+requestParams+"]";
			infoStr = Log4jPrintAspect.subStr(infoStr);
			logger.info(infoStr);
		} catch (Exception e) {
			logger.error(e);
		}
	}
	
	/**
	 * 清除存储信息
	 */
	private void removeMDC(){
		
		MDC.remove("ipAddress");
		MDC.remove("url");
		MDC.remove("tId");
		MDC.remove("reqId");
		MDC.remove("refer");
		MDC.remove("errno");
		MDC.remove("cost");
        MDC.remove("g_logid");
        MDC.remove("g_reqid");
	}
	
	public static String subStr(String str){
		String subStr = null;
		String max_logs_size = "100";//ConfigUtil.getString("max_logs_size");//配置文件配置每条日志最大字节数
		try {
			Integer subSLength = 100*1024; 	//默认100K
			if (StringUtils.isNotBlank(max_logs_size)) {
				subSLength = Integer.valueOf(max_logs_size)*1024;
			}
			byte[] a = str.getBytes();
            if (a.length <= subSLength) {
                subStr = str;
            } else if (subSLength > 0) {
                subStr = new String(a, 0, subSLength);
                int length = subStr.length();
                if (str.charAt(length - 1) != subStr.charAt(length - 1)) {
                    if (length < 2) {
                        subStr = null;
                    } else {
                        subStr = subStr.substring(0, length - 1);
                    }
                }
            }
		} catch (Exception e) {
			logger.error("截取日志字节数出错："+e.getMessage());
			e.printStackTrace();
		}
       
        return subStr;   
	}

	private String getIpAddress(HttpServletRequest request){
		String ipAddress = request.getHeader("x-forwarded-for");
		if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if(ipAddress.equals("127.0.0.1")){
				//根据本机配置的IP
				InetAddress inet=null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress= inet.getHostAddress();
			}
		}
		return ipAddress;
	}


	private String getRequestId(){
		StringBuffer stringBuffer = new StringBuffer();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String sdfStr = sdf.format(new Date());

		stringBuffer.append(sdfStr);
		Random random = new Random();
		for(int i = 0; i < 3; i++){
			stringBuffer.append(random.nextInt(10));//取三个随机数追加到stringBuffer
		}
		return stringBuffer.toString();
	}


	
}
